package sort.ui.gwt.client;

import sort.record.RandomRecordsFactory;
import sort.record.Record;
import sort.record.Records;
import sort.record.RecordsFactory;
import sort.result.SortResult;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

public class SortSingle implements EntryPoint {
//	private final SplitLayoutPanel panel = new SplitLayoutPanel();
	
	private final SortServiceAsync sortService = GWT.create(SortService.class);

	public static final int DEFAULT_RECORD_COUNT = 100;
//	private RecordsFactory factory;
	private Records records;
//	private Sorter sorter;
	
	@Override
	public void onModuleLoad() {
		final Button initButton = new Button("Init");
		final Button startButton = new Button("Start");
		final ListBox algoNameBox = new ListBox();
		final ResultTable resultTable = new ResultTable();
		final TextBox recCountTextBox = new TextBox();
		
		algoNameBox.addItem("sort.algorithm.BubbleSort");
		algoNameBox.addItem("sort.algorithm.BucketSort");
		algoNameBox.addItem("sort.algorithm.InsertionSort");
		algoNameBox.addItem("sort.algorithm.QuickSort");
		algoNameBox.addItem("sort.algorithm.SelectionSort");
		
		recCountTextBox.setValue(String.valueOf(DEFAULT_RECORD_COUNT));
		// We can add style names to widgets
//		btn.addStyleName("sendButton");
		RootPanel.get("controlPanelContainer").add(algoNameBox);
		RootPanel.get("controlPanelContainer").add(recCountTextBox);
		RootPanel.get("controlPanelContainer").add(initButton);
		RootPanel.get("controlPanelContainer").add(startButton);
		
		
		// 結果出力パネルの設定
		RootPanel.get("resultPanelContainer").add(resultTable);
		
		// エラー出力パネルの設定
		final HTML serverResponseLabel = new HTML();		
		RootPanel.get("errorLabelContainer").add(serverResponseLabel);
		
		// アニメーション出力パネルの設定
		final Canvas canvas = Canvas.createIfSupported();
		canvas.setSize("400px","400px");
		canvas.setCoordinateSpaceWidth(400);
		canvas.setCoordinateSpaceHeight(400);
		
//		final SortAnimationCanvas canvas = new SortAnimationCanvas(400,400);
//		final GWTCanvas canvas = new GWTCanvas(400,400);
//		canvas.setLineWidth(1);
//		canvas.setStrokeStyle(Color.RED);
//		canvas.beginPath();
//		canvas.moveTo(1, 1);
//		canvas.lineTo(1, 50);
//		canvas.lineTo(50, 50);
//		canvas.lineTo(50, 1);
//		canvas.closePath();
//		canvas.stroke();
//		
//		canvas.setFillStyle(Color.GREEN);
//		canvas.fillRect(100, 0, 200, 200);
		
		RootPanel.get("AnimationPanelContainer").add(canvas);
		
		
		
		// 初期化ボタンのイベントハンドラー
		initButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				RecordsFactory factory = RandomRecordsFactory.getInstance();
				records = factory.create(Integer.valueOf(recCountTextBox.getValue()));
				startButton.setEnabled(true);
				serverResponseLabel.setText("");
//				canvas.drawRecords(records);
				drawRecords(canvas.getContext2d(), records);
			}
		});
		
		// 開始ボタンのイベントハンドラー
		startButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				sendStart2Server();
			}
			
			private void sendStart2Server() {
				startButton.setEnabled(false);
				serverResponseLabel.setText("");
				sortService.sortServer(
								records
								,algoNameBox.getValue(algoNameBox.getSelectedIndex())
								, new AsyncCallback<SortResult>() {
									@Override
									public void onSuccess(SortResult result) {
//										canvas.drawRecords(result.getSortedRecords());
										drawRecords(canvas.getContext2d(), result.getSortedRecords());
										resultTable.add(result);
									}
									
									@Override
									public void onFailure(Throwable caught) {
										// エラー処理
										StringBuffer errmsg = new StringBuffer();
//										errmsg.append("<pre>");
										errmsg.append(caught.toString()).append("<br>");
//										errmsg.append(caught.getMessage()).append("<br>");
										for ( int i=0; i<caught.getStackTrace().length; i++ ) {
											errmsg.append(caught.getStackTrace()[i].toString()).append("<br>");
										}
//										errmsg.append("</pre>");
										serverResponseLabel.setHTML(errmsg.toString());
										
									}
								}
								);
			}
		});
		
		startButton.setEnabled(false);
	}

	public static final int LINE_WIDTH=1;
	private void drawRecords(Context2d context,Records records) {
		int lin_w = LINE_WIDTH;
		// 画面クリア
		context.clearRect(0, 0, 400, 400);
		// 描画
		for (int x=0;x<records.size();x++) {
			Record r = records.get(x);
			context.setFillStyle("CYAN");
			context.fillRect(x*lin_w, 0, lin_w, r.getKey());
			context.setFillStyle("BLUE");
			context.fillRect(x*lin_w,r.getKey(),lin_w,1);
		}
	}
}
